package view.mt4j.scene.project;

import java.beans.PropertyChangeEvent;

import model.ApplicationModel;
import model.Project;
import model.Workspace;

import org.mt4j.MTApplication;
import org.mt4j.components.MTComponent;
import org.mt4j.input.inputProcessors.IGestureEventListener;
import org.mt4j.input.inputProcessors.MTGestureEvent;
import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragEvent;
import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragProcessor;
import org.mt4j.input.inputProcessors.globalProcessors.CursorTracer;
import org.mt4j.sceneManagement.AbstractScene;
import org.mt4j.util.math.ToolsGeometry;
import org.mt4j.util.math.Vector3D;

import controller.ApplicationController;
import controller.view.ProjectController;
import controller.view.WorkspaceController;

import util.CollectionChangeEvent;
import view.interfaces.screen.project.ProjectView;
import view.mt4j.workspace.WorkspaceViewImpl;

import static app.ViewConstants.*;

public class ProjectScene extends AbstractScene implements ProjectView {

	private ApplicationModel model;
	private Project project;
	private ApplicationController applicationController;
	private ProjectController projectController;
	// private MTRectangle background;
	private ProjectMainMenu projectMainMenu;

	public ProjectScene(MTApplication mtApplication, ApplicationModel model) {
		super(mtApplication, "ProjectScene");
		this.model = model;
		this.model.addPropertyChangeListener(
				ApplicationModel.Property.CURRENT_PROJECT, this);
		// Set the background color
		this.setClearColor(PROJECT_BACKGROUND_COLOR);

		this.registerGlobalInputProcessor(new CursorTracer(mtApplication, this));

		addMainMenu();

		// MTRadialMenu radialMenu = new MTRadialMenu(getMTApplication(), new
		// Vector3D(mtApplication.width / 2f,
		// mtApplication.height / 4f), FontManager
		// .getInstance().createFont(mtApplication, "arial.ttf", 50,
		// MTColor.WHITE), scaleFactor, menuItems)
	}

	@Override
	public void setController(ApplicationController applicationController) {
		this.applicationController = applicationController;
		this.projectController = applicationController.getProjectController();
		this.projectMainMenu
				.setApplicationController(this.applicationController);
	}

	private void addMainMenu() {
		projectMainMenu = new ProjectMainMenu(getMTApplication());
		this.getCanvas().addChild(projectMainMenu);
		projectMainMenu.addGestureListener(DragProcessor.class,
				new IGestureEventListener() {

					@Override
					public boolean processGestureEvent(MTGestureEvent ge) {
						DragEvent de = (DragEvent) ge;

						projectMainMenu.translateGlobal(de.getTranslationVect());

						Vector3D[] v1 = new Vector3D[] {
								new Vector3D(0, 0),
								new Vector3D(0, getMTApplication().screenHeight),
								new Vector3D(getMTApplication().screenWidth,
										getMTApplication().screenHeight),
								new Vector3D(getMTApplication().screenWidth, 0),
								new Vector3D(0, 0) };
						Vector3D[] v2 = projectMainMenu.getBounds()
								.getVectorsGlobal();
						boolean inside = true;
						for (Vector3D vector3d : v2) {
							if (!ToolsGeometry.isPolygonContainsPoint(v1,
									vector3d)) {
								inside = false;
							}
						}
						if (!inside) {
							projectMainMenu.translateGlobal(de
									.getTranslationVect().getScaled(-1));
						}
						return false;
					}
				});
		projectMainMenu.setPositionRelativeToParent(new Vector3D(
				getMTApplication().width * 9f / 10f,
				getMTApplication().height * 9f / 10f));
	}

	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		if (evt.getPropertyName().equals(
				ApplicationModel.Property.CURRENT_PROJECT.name())) {
			if (project != null) {
				project.removeAllListener();
			}
			project = (Project) evt.getNewValue();
			projectController.setProject(project);
			applicationController.showProjectView();
			project.addOpenedWorkspaceCollectionChangeListener(this);
		}
	}

	@Override
	public void collectionChanged(CollectionChangeEvent<Workspace> ev) {
		if (ev.getType().name().equals(CollectionChangeEvent.Type.ADD.name())) {
			Workspace workspace = ev.getItem();
			WorkspaceViewImpl workspaceView = new WorkspaceViewImpl(
					getMTApplication(), workspace);
			WorkspaceController workspaceController = projectController
					.createWorkspaceController(workspace, workspaceView);
			workspaceView.setController(applicationController,
					workspaceController);

			this.getCanvas().addChild(workspaceView);
			workspaceView.setLocation(
					getMTApplication().width / 2f - workspace.getSize().width
							/ 2f,
					getMTApplication().height / 2f - workspace.getSize().height
							/ 2f);
		} else if (ev.getType().name()
				.equals(CollectionChangeEvent.Type.REMOVE.name())) {
			Workspace workspace = ev.getItem();
			for (MTComponent child : this.getCanvas().getChildren()) {
				if (child instanceof WorkspaceViewImpl
						&& ((WorkspaceViewImpl) child).getWorkspace() == workspace) {
					this.getCanvas().removeChild(child);
				}
			}
		}

	}
}